using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using PastCrew.Games.Chess.Engine.Entities;
using Engine = PastCrew.Games.Chess.Engine;

namespace TestChess
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class UnitTestChessEngine
    {
        public UnitTestChessEngine()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion
               

        [TestInitialize]
        public void ChessInit()
        {

        }

        #region positive tests

        #region miscellaneous

        [TestMethod]
        public void Test_Miscellaneous_Threatened()
        {
            Engine.Entities.Board.SetupBoard();            

            Engine.Entities.Board.Position threatenedPosition = new Engine.Entities.Board.Position('c', 6);
            List<Engine.Entities.Pieces.BasePiece> list = Board.GetSquare(threatenedPosition).GetThreatenedByList(Engine.Entities.Color.white);
            int count = list.Count;
            Assert.IsTrue(count == 3, "Square c6 is threatened by a7, b8 and c7");
        }

        #endregion

        #region pawn

        /// <summary>
        /// From start position, move white pawn one place forward
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_WhitePawn_MoveOneForward()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 2);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('f', 3);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward one position failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after pawn moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after pawn moved to it");            
        }

        /// <summary>
        /// From start position, move black pawn one place forward
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_BlackPawn_MoveOneForward()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('b', 7);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('b', 6);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward one position failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after pawn moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after pawn moved to it");            
        }

        /// <summary>
        /// From start position, move white pawn two places forward
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_WhitePawn_MoveTwoForward()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 2);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('f', 4);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward two positions failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after pawn moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after pawn moved to it");            
        }

        /// <summary>
        /// From start position, move black pawn two places forward
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_BlackPawn_MoveTwoForward()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('b', 7);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('b', 5);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward two positions failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after pawn moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after pawn moved to it");            
        }

        /// <summary>
        /// From start position, move white pawn diagonally, taking black pawn
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_WhitePawn_MoveDiagonallyTakingBlackPawn()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 2);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('g', 3);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Spawn pawn
            Engine.Entities.Pieces.Pawn pawn = new Engine.Entities.Pieces.Pawn();
            pawn.Color = Engine.Entities.Color.black;
            squareTarget.Occupant = pawn;

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move diagonally, taking black pawn failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after pawn moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after pawn moved to it");
            Assert.IsTrue(squareTarget.Occupant.Color == Engine.Entities.Color.white, "Target square must have white pawn after taking black pawn");
        }

        /// <summary>
        /// From start position, move black pawn diagonally, taking white pawn
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_BlackPawn_MoveDiagonallyTakingWhitePawn()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 7);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('g', 6);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Spawn pawn
            Engine.Entities.Pieces.Pawn pawn = new Engine.Entities.Pieces.Pawn();
            pawn.Color = Engine.Entities.Color.white;
            squareTarget.Occupant = pawn;

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move diagonally, taking white pawn failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after pawn moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after pawn moved to it");
            Assert.IsTrue(squareTarget.Occupant.Color == Engine.Entities.Color.black, "Target square must have black pawn after taking black pawn");
        }

        [TestMethod]
        public void Test_WhitePawn_History()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 2);
            Engine.Entities.Board.Position posTarget1 = new Engine.Entities.Board.Position('f', 3);
            Engine.Entities.Board.Position posTarget2 = new Engine.Entities.Board.Position('f', 4);

            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget1), "Move forward step 1 failed");
            Engine.Entities.Board.Square squareTarget1 = Board.GetSquare(posTarget1);
            Assert.IsTrue(Board.MovePiece(squareTarget1.Occupant, posTarget2), "Move forward step 1 failed");
            Engine.Entities.Board.Square squareTarget2 = Board.GetSquare(posTarget2);

            Engine.Entities.Board.Position previousPosition = squareTarget2.Occupant.GetPreviousPosition();

            Assert.IsTrue(previousPosition.Horizontal == 'F', "Previous Position horizontal should be 'f'");
            Assert.IsTrue(previousPosition.Vertical == 3, "Previous Position vertical should be 3");
        }

        #endregion

        #region knight

        [TestMethod]
        public void Test_WhiteKnight_Move2Forward1Right()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('b', 1);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('c', 3);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward right failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after knight moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after knight moved to it");            
        }

        [TestMethod]
        public void Test_WhiteKnight_Move2Backward1Left()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 5);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('e', 3);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Spawn knight
            Engine.Entities.Pieces.Knight knight = new Engine.Entities.Pieces.Knight();
            knight.Color = Engine.Entities.Color.white;
            squareCurrent.Occupant = knight;


            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move backward left failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after knight moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after knight moved to it");
        }

        [TestMethod]
        public void Test_BlackKnight_Move2Forward1Right()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('b', 8);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('c', 6);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward right failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after knight moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after knight moved to it");
        }

        [TestMethod]
        public void Test_BlackKnight_Move2Backward1Left()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 4);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('e', 6);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Spawn knight
            Engine.Entities.Pieces.Knight knight = new Engine.Entities.Pieces.Knight();
            knight.Color = Engine.Entities.Color.black;
            squareCurrent.Occupant = knight;


            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move backward left failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after knight moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after knight moved to it");
        }

        [TestMethod]
        public void Test_WhiteKnight_Move2Forward1RightTakingBlackPawn()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('b', 1);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('c', 3);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Spawn pawn
            Engine.Entities.Pieces.Pawn pawn = new Engine.Entities.Pieces.Pawn();
            pawn.Color = Engine.Entities.Color.black;
            squareTarget.Occupant = pawn;

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward taking black pawn failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after knight moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after knight moved to it");
            Assert.IsTrue(squareTarget.Occupant.Color == PastCrew.Games.Chess.Engine.Entities.Color.white, "Target square must have white knight as occupant");
        }

        [TestMethod]
        public void Test_BlackKnight_Move2Forward1RightTakingWhitePawn()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('b', 8);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('c', 6);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Spawn pawn
            Engine.Entities.Pieces.Pawn pawn = new Engine.Entities.Pieces.Pawn();
            pawn.Color = Engine.Entities.Color.white;
            squareTarget.Occupant = pawn;

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward taking white pawn failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after knight moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after knight moved to it");
            Assert.IsTrue(squareTarget.Occupant.Color == PastCrew.Games.Chess.Engine.Entities.Color.black, "Target square must have black knight as occupant");
        }

        #endregion

        #region bishop

        [TestMethod]
        public void Test_WhiteBishop_MoveDiagonalLeft()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 1);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('a', 6);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Remove obstructing white pawn
            Engine.Entities.Board.Position obstructingPawn = new Engine.Entities.Board.Position('e', 2);
            Engine.Entities.Board.Square squareObstructingPawn = Board.GetSquare(obstructingPawn);
            squareObstructingPawn.Occupied = false;

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move diagonally left failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after bishop moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after bishop moved to it");            
        }

        [TestMethod]
        public void Test_BlackBishop_MoveDiagonalLeft()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 8);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('a', 3);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Remove obstructing black pawn
            Engine.Entities.Board.Position obstructingPawn = new Engine.Entities.Board.Position('e', 7);
            Engine.Entities.Board.Square squareObstructingPawn = Board.GetSquare(obstructingPawn);
            squareObstructingPawn.Occupied = false;

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move diagonally left failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after bishop moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after bishop moved to it");
        }

        #endregion

        #region king

        [TestMethod]
        public void Test_WhiteKing_MoveForward()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('e', 1);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('e', 2);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Remove obstructing black pawn
            Engine.Entities.Board.Position obstructingPawn = new Engine.Entities.Board.Position('e', 2);
            Engine.Entities.Board.Square squareObstructingPawn = Board.GetSquare(obstructingPawn);
            squareObstructingPawn.Occupied = false;

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after king moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after king moved to it");
        }

        [TestMethod]
        public void Test_BlackKing_MoveForward()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('e', 8);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('e', 7);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Remove obstructing black pawn
            Engine.Entities.Board.Position obstructingPawn = new Engine.Entities.Board.Position('e', 7);
            Engine.Entities.Board.Square squareObstructingPawn = Board.GetSquare(obstructingPawn);
            squareObstructingPawn.Occupied = false;

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after king moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after king moved to it");
        }

        [TestMethod]
        public void Test_WhiteKing_MoveDiagonalRightForward()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('e', 1);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('f', 2);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Remove obstructing black pawn
            Engine.Entities.Board.Position obstructingPawn = new Engine.Entities.Board.Position('f', 2);
            Engine.Entities.Board.Square squareObstructingPawn = Board.GetSquare(obstructingPawn);
            squareObstructingPawn.Occupied = false;

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after king moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after king moved to it");
        }

        [TestMethod]
        public void Test_BlackKing_MoveDiagonalRightForward()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('e', 8);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('f', 7);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Remove obstructing black pawn
            Engine.Entities.Board.Position obstructingPawn = new Engine.Entities.Board.Position('f', 7);
            Engine.Entities.Board.Square squareObstructingPawn = Board.GetSquare(obstructingPawn);
            squareObstructingPawn.Occupied = false;

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after king moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after king moved to it");
        }

        [TestMethod]
        public void Test_WhiteKing_MoveDiagonalRightForwardTakingBlackPawn()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('e', 1);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('f', 2);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Remove obstructing black pawn
            Engine.Entities.Board.Position obstructingPawn = new Engine.Entities.Board.Position('f', 2);
            Engine.Entities.Board.Square squareObstructingPawn = Board.GetSquare(obstructingPawn);
            squareObstructingPawn.Occupied = false;

            // Spawn black pawn
            Engine.Entities.Pieces.Pawn pawn = new Engine.Entities.Pieces.Pawn();
            pawn.Color = Engine.Entities.Color.black;
            squareTarget.Occupant = pawn;

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after king moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after king moved to it");
        }

        [TestMethod]
        public void Test_BlackKing_MoveDiagonalRightForwardTakingWhitePawn()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('e', 8);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('f', 7);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Remove obstructing black pawn
            Engine.Entities.Board.Position obstructingPawn = new Engine.Entities.Board.Position('f', 7);
            Engine.Entities.Board.Square squareObstructingPawn = Board.GetSquare(obstructingPawn);
            squareObstructingPawn.Occupied = false;

            // Spawn black pawn
            Engine.Entities.Pieces.Pawn pawn = new Engine.Entities.Pieces.Pawn();
            pawn.Color = Engine.Entities.Color.white;
            squareTarget.Occupant = pawn;

            Assert.IsTrue(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward failed");
            Assert.IsTrue(!squareCurrent.Occupied, "Current square must be empty after king moved from it");
            Assert.IsTrue(squareTarget.Occupied, "Target square must have occupant after king moved to it");
        }

        [TestMethod]
        public void Test_WhiteKing_Castling()
        {
            Assert.IsTrue(false, "Not implemented");
        }

        [TestMethod]
        public void Test_BlackKing_Castling()
        {
            Assert.IsTrue(false, "Not implemented");
        }      

        #endregion

        #endregion

        #region negative tests

        #region miscellaneous

        [TestMethod]
        public void Test_Miscellaneous_NotThreatened()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position threatenedPosition = new Engine.Entities.Board.Position('d', 5);
            List<Engine.Entities.Pieces.BasePiece> list1 = Board.GetSquare(threatenedPosition).GetThreatenedByList(Engine.Entities.Color.white);
            List<Engine.Entities.Pieces.BasePiece> list2 = Board.GetSquare(threatenedPosition).GetThreatenedByList(Engine.Entities.Color.black);
            int count1 = list1.Count;
            int count2 = list2.Count;
            Assert.IsTrue(count1 == 0 && count2 == 0, "Square d4 is not threatened ({0}, {1})", count1, count2);

        }

        #endregion

        #region pawn

        /// <summary>
        /// From start position, move white pawn one place backward to occupied field
        /// From spawn postiion, move white pawn one place backward to unoccupied field
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_WhitePawn_MoveOneBackwards()
        {
            Engine.Entities.Board.SetupBoard();
                        
            // Field occupied (Bishop)
            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 2);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('f', 1);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move backward to occupied field should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must still be occupied after illegal move attempt");

            // Field empty
            posCurrent = new Engine.Entities.Board.Position('f', 5);
            posTarget = new Engine.Entities.Board.Position('f', 4);
            squareCurrent = Board.GetSquare(posCurrent);
            squareTarget = Board.GetSquare(posTarget);
            // Spawn pawn
            Engine.Entities.Pieces.Pawn pawn = new Engine.Entities.Pieces.Pawn();
            pawn.Color = Engine.Entities.Color.white;
            squareCurrent.Occupant = pawn;

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move backward for pawn should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must still be occupied after illegal move attempt");
            Assert.IsFalse(squareTarget.Occupied, "Target square must still be empty after illegal move attempt");
        }

        /// <summary>
        /// From start position, move black pawn one place backward to occupied field
        /// From spawn postiion, move black pawn one place backward to unoccupied field
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_BlackPawn_MoveOneBackwards()
        {
            Engine.Entities.Board.SetupBoard();

            // Field occupied (Bishop)
            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 7);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('f', 8);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move backward to occupied field should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must still be occupied after illegal move attempt");

            // Field empty
            posCurrent = new Engine.Entities.Board.Position('f', 4);
            posTarget = new Engine.Entities.Board.Position('f', 5);
            squareCurrent = Board.GetSquare(posCurrent);
            squareTarget = Board.GetSquare(posTarget);
            // Spawn pawn
            Engine.Entities.Pieces.Pawn pawn = new Engine.Entities.Pieces.Pawn();
            pawn.Color = Engine.Entities.Color.black;
            squareCurrent.Occupant = pawn;

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move backward for pawn should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must still be occupied after illegal move attempt");
            Assert.IsFalse(squareTarget.Occupied, "Target square must still be empty after illegal move attempt");
        }

        /// <summary>
        /// From start position, move white pawn diagonally
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_WhitePawn_MoveDiagonally()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 2);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('g', 3);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move diagonally should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal diagonal move attempt");
            Assert.IsFalse(squareTarget.Occupied, "Target square must not have occupant after illegal diagonal move attempt");   
        }

        /// <summary>
        /// From start position, move black pawn diagonally
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_BlackPawn_MoveDiagonally()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 7);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('g', 6);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move diagonally should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal diagonal move attempt");
            Assert.IsFalse(squareTarget.Occupied, "Target square must not have occupant after illegal diagonal move attempt");
        }

        /// <summary>
        /// From start position, move white pawn diagonally, taking white pawn
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_WhitePawn_MoveDiagonallyTakingWhitePawn()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 2);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('g', 3);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Spawn pawn
            Engine.Entities.Pieces.Pawn pawn = new Engine.Entities.Pieces.Pawn();
            pawn.Color = Engine.Entities.Color.white;
            squareTarget.Occupant = pawn;

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move diagonally should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal diagonal move attempt");
        }

        /// <summary>
        /// From start position, move black pawn diagonally, taking black pawn
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_BlackPawn_MoveDiagonallyTakingBlackPawn()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 7);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('g', 6);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Spawn pawn
            Engine.Entities.Pieces.Pawn pawn = new Engine.Entities.Pieces.Pawn();
            pawn.Color = Engine.Entities.Color.black;
            squareTarget.Occupant = pawn;

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move diagonally should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal diagonal move attempt");
        }

        /// <summary>
        /// From spawned position, move white pawn sideways
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_WhitePawn_MoveSideways()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 4);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('g', 4);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            // Spawn white pawn
            Engine.Entities.Pieces.Pawn whitePawn = new Engine.Entities.Pieces.Pawn();
            whitePawn.Color = Engine.Entities.Color.white;
            squareCurrent.Occupant = whitePawn;

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move sideways should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal sideways move attempt");
        }

        /// <summary>
        /// From spawned position, move black pawn sideways
        /// </summary>
        /// <remarks>
        /// Assumes Default Start Board positions
        /// </remarks>
        [TestMethod]
        public void Test_BlackPawn_MoveSideways()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 5);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('g', 5);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            //Spawn black pawn
            Engine.Entities.Pieces.Pawn blackPawn = new Engine.Entities.Pieces.Pawn();
            blackPawn.Color = Engine.Entities.Color.black;
            squareCurrent.Occupant = blackPawn;

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move sideways should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal sideways move attempt");
        }

        #endregion

        #region knight

        [TestMethod]
        public void Test_WhiteKnight_Move2Forward()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('b', 1);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('b', 3);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal forward move attempt");
        }

        [TestMethod]
        public void Test_BlackKnight_Move2Forward()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('b', 8);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('b', 6);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal forward move attempt");
        }

        [TestMethod]
        public void Test_WhiteKnight_Move2Forward1RightTakingWhitePawn()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('b', 1);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('c', 3);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            //Spawn white pawn
            Engine.Entities.Pieces.Pawn whitePawn = new Engine.Entities.Pieces.Pawn();
            whitePawn.Color = Engine.Entities.Color.white;
            squareTarget.Occupant = whitePawn;

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward taking the white pawn should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal forward move attempt");
        }

        [TestMethod]
        public void Test_BlackKnight_Move2Forward1RightTakingBlackPawn()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('b', 8);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('c', 6);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            //Spawn black pawn
            Engine.Entities.Pieces.Pawn blackPawn = new Engine.Entities.Pieces.Pawn();
            blackPawn.Color = Engine.Entities.Color.black;
            squareTarget.Occupant = blackPawn;

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward taking the black pawn should fail");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal forward move attempt");
        }

        #endregion

        #region bishop

        [TestMethod]
        public void Test_WhiteBishop_MoveDiagonalLeftObstructed()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 1);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('a', 6);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);
                        
            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move diagonally should fail due to obstruction");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal move attempt");
            Assert.IsTrue(!squareTarget.Occupied, "Target square must not have occupant after illegal move attempt");
        }

        [TestMethod]
        public void Test_BlackBishop_MoveDiagonalLeftObstructed()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('f', 8);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('a', 3);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move diagonally should fail due to obstruction");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal move attempt");
            Assert.IsTrue(!squareTarget.Occupied, "Target square must not have occupant after illegal move attempt");
        }

        #endregion

        #region king

        [TestMethod]
        public void Test_WhiteKing_MoveForwardObstructed()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('e', 1);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('e', 2);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward should fail due to obstruction");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal move attempt");            
        }

        [TestMethod]
        public void Test_BlackKing_MoveForwardObstructed()
        {
            Engine.Entities.Board.SetupBoard();

            Engine.Entities.Board.Position posCurrent = new Engine.Entities.Board.Position('e', 8);
            Engine.Entities.Board.Position posTarget = new Engine.Entities.Board.Position('e', 7);
            Engine.Entities.Board.Square squareCurrent = Board.GetSquare(posCurrent);
            Engine.Entities.Board.Square squareTarget = Board.GetSquare(posTarget);

            Assert.IsFalse(Board.MovePiece(squareCurrent.Occupant, posTarget), "Move forward should fail due to obstruction");
            Assert.IsTrue(squareCurrent.Occupied, "Current square must not be empty after illegal move attempt");            
        }

        [TestMethod]
        public void Test_WhiteKing_CastlingThreatened()
        {
            Assert.IsTrue(false, "Not implemented");
        }

        [TestMethod]
        public void Test_BlackKing_CastlingThreatened()
        {
            Assert.IsTrue(false, "Not implemented");
        }

        [TestMethod]
        public void Test_WhiteKing_CastlingMoved()
        {
            Assert.IsTrue(false, "Not implemented");
        }

        [TestMethod]
        public void Test_BlackKing_CastlingMoved()
        {
            Assert.IsTrue(false, "Not implemented");
        }

        [TestMethod]
        public void Test_WhiteKing_CastlingBlocked()
        {
            Assert.IsTrue(false, "Not implemented");
        }

        [TestMethod]
        public void Test_BlackKing_CastlingBlocked()
        {
            Assert.IsTrue(false, "Not implemented");
        }

        #endregion

        #endregion
    }
}
